package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	funnel := NewFunnel(0.5, 10)

	for i := 0; i < 30; i++ {
		if funnel.Pour(1) {
			fmt.Println("request success!!")
		} else {
			fmt.Println("request failed!!")
		}

		time.Sleep(time.Millisecond * 1000)
	}
}

type Funnel struct {
	rate       float64
	capacity   float64
	remaining  float64
	lastUpdate time.Time
	lock       sync.Mutex
}

func NewFunnel(rate, capacity float64) *Funnel {
	return &Funnel{
		rate:       rate,
		capacity:   capacity,
		remaining:  capacity,
		lastUpdate: time.Now(),
	}
}

func (f *Funnel) Pour(amount float64) bool {
	f.lock.Lock()
	defer f.lock.Unlock()

	now := time.Now()
	elapsed := now.Sub(f.lastUpdate).Seconds()
	f.lastUpdate = time.Now()

	f.remaining += elapsed * f.rate
	fmt.Println("当前流出个数：", f.remaining)
	if f.remaining > f.capacity {
		f.remaining = f.capacity
	}

	if amount <= f.remaining {
		f.remaining -= amount
		return true
	}

	return false

}
